package com.sc.byahi.user.client;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sc.byahi.user.client.components.maps.InfoWindow;
import com.sc.byahi.user.client.components.maps.LatLng;
import com.sc.byahi.user.client.components.maps.MClickEvent;
import com.sc.byahi.user.client.components.maps.MClickHandler;
import com.sc.byahi.user.client.components.maps.MapOptions;
import com.sc.byahi.user.client.components.maps.MapWidget;
import com.sc.byahi.user.client.components.maps.Marker;
import com.sc.byahi.user.client.components.maps.MarkerOptions;
import com.sc.byahi.user.client.components.maps.clusterer.MarkerClusterer;
import com.sc.byahi.user.shared.Profile;
import com.sc.byahi.user.shared.ProfileVO;

public class ProfileListMapView extends ProfileResultView implements ICleaner {
	// private Logger logger = Logger.getLogger("ProfileListMapView");
	private Map<Long, Marker> profileMap = new HashMap<Long, Marker>();
	private ProfileViewDiv currentDisplayProfile = null;

//	private SimplePanel simpleMapHolderPanel = new SimplePanel();
	private MapWidget map;
	private static MarkerClusterer clusterer;

	private void createAndAttachMap() {
		// MapHelper.createAndAttachMap(map, simpleMapHolderPanel, "690px", "800px");
//		simpleMapHolderPanel.clear();
		if (map == null) {
			MapOptions mapOptions = MapOptions.newInstance();
			mapOptions.setZoom(5);
			mapOptions.setMapTypeId("ROADMAP");
			map = new MapWidget(mapOptions);
			map.setSize("690px", "800px");
			map.getJso().setCenter(MapHelper.DEFAULT);
		} else {
			map.getJso().setZoom(5);
			map.getJso().setCenter(MapHelper.DEFAULT);
		}
//		simpleMapHolderPanel.add(map);
		clusterer = MarkerClusterer.newInstance(map);
	}

	@Override
	public void clean() {
		removeMarker(profileMap.keySet().toArray(new Long[0]));
		profileMap.clear();// just in case
		currentDisplayProfile = null;
		// MapHelper.getInstance().resizeMap(MapHelper.getInstance().getMap());
		super.clean();
	}

	public ProfileListMapView() {
		VerticalPanel panel = new VerticalPanel();
		// simpleMapHolderPanel.setWidth("690px");
		// simpleMapHolderPanel.setHeight("800px");
		// panel.add(simpleMapHolderPanel);
		createAndAttachMap();
		panel.add(map);
		resize();
		initWidget(panel);
	}

	public void resize() {
		// TODO: Resize so that map gets display correctly
		// MapHelper.getInstance().panMapToDefaultPosition();
		// map.checkResize();
		// map.setCenter(DEFAULT);
		// map.setZoom(13);
		map.triggerResize();
	}

	private void removeMarker(Long... id) {
		// MapImpl nullMap = null;
		InfoWindow.closeExistingInfoWindow();
		for (Long long1 : id) {
			if (profileMap.containsKey(long1)) {
				clusterer.removeMarker(profileMap.get(long1));
				profileMap.get(long1).clear();
				profileMap.remove(long1);
				profileMap.keySet().remove(long1);
			}
		}
	}

	public void hideProfile(Long id) {
		removeMarker(id);
	}

	public void redrawProfile(Profile profile) {
		if (super.currProfiles.containsKey(profile.getId())) {
			super.currProfiles.put(profile.getId(), profile);
		}
		if (currentDisplayProfile != null)
			currentDisplayProfile.showData(profile);
		// UIUtil.showDialog(Arrays.asList("Please close this window and open again to see changes."), "Profile Updated");
	}

	public void redrawView() {
		clean();
		createAndAttachMap();
		GreetingService.Util.getInstance().findPublicProfilesMapDetailsByIds(data, new AsyncCallback<List<ProfileVO>>() {

			@Override
			public void onSuccess(List<ProfileVO> result) {
				List<Marker> markerList = new ArrayList<Marker>();
				for (final ProfileVO p : result) {
					if (p.getCurrLatitude() == null || p.getCurrLongitude() == null) {
						continue;// no mapping for unapproved profiles
					}
					final LatLng point = LatLng.getInstance(p.getCurrLatitude(), p.getCurrLongitude());

					MarkerOptions markerOptions = MarkerOptions.getInstance();
					markerOptions.setPosition(point);
					Marker marker = Marker.getInstance(markerOptions);
					markerList.add(marker);
					// MapHelper.getInstance().panMapToPosition(point);

					marker.addClickHandler(new MClickHandler() {

						@Override
						public void onEvent(MClickEvent event) {
							GreetingService.Util.getInstance().findPublicProfilesByIds(Arrays.asList(p.getId()), new AsyncCallback<List<Profile>>() {

								@Override
								public void onSuccess(List<Profile> result) {
									if (!result.isEmpty()) {
										currentDisplayProfile = new ProfileViewDiv(true);
										currentDisplayProfile.setOwnData(ownData);
										currentDisplayProfile.showData(result.get(0));
										MapHelper.getInstance().createInfoWindow(map, point, currentDisplayProfile);
									}
								}

								@Override
								public void onFailure(Throwable caught) {
									UIUtil.showGenericFailureDialog();
								}
							});
						}
					});

					profileMap.put(p.getId(), marker);
				}
				clusterer.addMarkers(markerList);
				resize();
			}

			@Override
			public void onFailure(Throwable caught) {
				UIUtil.showGenericFailureDialog();
			}
		});

	}

	public Widget asWidget() {
		return this;
	}

}
